home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 361_01 / rampage.c < prev    next >
C/C++ Source or Header  |  1991-09-18  |  7KB  |  175 lines

  1.  
  2.  
  3. /* RamPage.c ---> Transparently Manage a Page of RAM & a File.
  4.  *
  5.  * J.Ekwall                                             11 January 91
  6.  *
  7.  * Copyrighted to the Public Domain.  Unlimited Distribution Authorized.
  8.  *
  9.  * User Assumes All Risks/Liabilities.
  10.  *
  11.  * Last Update: 18 September 91/EK
  12.  */
  13.  
  14. /* Notes:
  15.       1. "Puka"  (Poo'-kah) is an Hawaiian Pigeon Hole.
  16.       2. "Nui"   (New'-E)   is    Hawaiian for "Big".
  17.       3. "Pau"   (Pow)      is    Hawaiian for "End" or "Finished".
  18.       4. "Dkine" (da-kIn')  is    Hawaiian for "That".
  19.  
  20. How it Works:
  21.  
  22.    An Array of File Pointers is created when a File is "Loaded".  When a Line
  23. is changed, this Array is altered to point at the text of that Line stored in
  24. a "Page" of RAM.  When that "Page" gets full, the file is "Saved" by renaming
  25. it w/ a ".BAK" extension and writing a new one under the original name,
  26. pulling text from the original file and RAM guided by the Array, which is
  27. updated to point at the New File.
  28.  
  29.    The above Array ("NuiPuka") doesn't really exist.  A macro redirects Array
  30. access actions to an array of pointers, each of which points to a dynamically
  31. allocated array of 1024 long integers (4K of RAM).  In other words, small
  32. files use the RAM-Page plus 4K, larger files consume 4K for each additonal
  33. 1024 lines (or fraction thereof), a real RAM savings. */
  34.  
  35. #include <ctype.h>
  36. #include <stdio.h>
  37. #include <stdlib.h>
  38. #include <string.h>
  39. #include <stdek.h>
  40. #include <gadgets.h>
  41.  
  42.  
  43. /* Declare Local Macros */
  44. #define NuiPuka(x)    Puka[(x)/1024][(x)%1024]
  45.  
  46. /* Declare Globals */
  47. long SizeOfRamPage = 65534L;                    /* User Adjustable */
  48.  
  49. /* Declare Structures, Unions & TypeDefs */
  50. typedef long far * PtrPuka;
  51. static PtrPuka Puka[32];
  52.  
  53. /* Declar Local Prototypes */
  54. static int  PtrAlloc(void);
  55.  
  56. int Rampage(char *Dkine, char *Text, int Index)
  57. {
  58.     int i;
  59.     static int Dirty = 0, Fill, Nuff, StrPau;
  60.     static unsigned int NuiPukaPau = 0, Pau;
  61.     static char FileName[81], far *RamPage = NULL;
  62.     static FILE *fp;
  63.  
  64.     if (!(Index >= 1 && Index <= max(Pau, 1))) return Pau;
  65.     if (Pau > 32767U) { Rampage("Close", NULL, 1); exit(1); }
  66.     if (fp IS NULL && toupper(*Dkine) != 'L') return 0;
  67.     
  68.     switch (toupper(*Dkine)) {
  69.     case 'F':                                           /* Fetch */
  70.        if (Index IS Pau) { strcpy(Text, "~"); return 0; }
  71.        else if (NuiPuka(Index) < 0x400) 
  72.           strcpy(Text, RamPage+StrPau*NuiPuka(Index));
  73.        else {
  74.           auto char *tp1;
  75.        
  76.           fseek(fp, NuiPuka(Index)-0x400, SEEK_SET); fgets(Text, 255, fp);
  77.           if ((tp1 = strrchr(Text, NL)) != NULL) *tp1 = NULL;
  78.        }
  79.        break;
  80.     case 'I':                                           /* Insert */
  81.        if (Pau IS NuiPukaPau) NuiPukaPau += PtrAlloc();
  82.        for (i = Pau++; i >= Index; i--) NuiPuka(i+1) = NuiPuka(i);
  83.        NuiPuka(Index) = 0x1000;
  84.     case 'P':                                           /* Push */
  85.        if (Index IS Pau) {
  86.           NuiPuka(Pau) = 0x1000;
  87.           if (Pau++ IS NuiPukaPau) NuiPukaPau += PtrAlloc();
  88.        }
  89.        if (NuiPuka(Index) < 0x400)
  90.           strcpy(RamPage+StrPau*NuiPuka(Index), Text);
  91.        else {
  92.           if (strlen(Text) > StrPau) {
  93.              if (strlen(Text) > 255) Text[256] = NULL;
  94.              Rampage("Save", "", 1); StrPau = min(strlen(Text)+11, 255);
  95.              Nuff = min(SizeOfRamPage/StrPau, 1023);
  96.           }
  97.           if (Fill >= Nuff) Rampage("Save", "", 1); NuiPuka(Index) = Fill;
  98.           strcpy(RamPage + StrPau*Fill, Text); Fill++;
  99.        }
  100.        Dirty++; return Pau;
  101.     case 'D':                                           /* Delete */
  102.        if (Index < 1 || Index >= Pau) return FALSE;
  103.        for (i = Index; i < Pau; i++) NuiPuka(i) = NuiPuka(i+1);
  104.        Dirty++; return --Pau;
  105.     case 'S':                                           /* Save */
  106.        if (Dirty || *Text) {
  107.           auto char Line[256];
  108.  
  109.           if (Dirty) {
  110.              auto char BakFileName[81];
  111.              auto FILE *wfp;
  112.  
  113.              NewExt(FileName, BakFileName, ".BAK"); fclose(fp);
  114.              if (stricmp(FileName, BakFileName)) unlink(BakFileName);
  115.              else { tmpnam(BakFileName); Index = 0; }
  116.              rename(FileName, BakFileName);
  117.              fp = fopen(BakFileName, "r"); wfp = fopen(FileName, "w");
  118.              for (i = 1; i < Pau; i++) {
  119.                 Rampage("Fetch", Line, i); NuiPuka(i)   = ftell(wfp) + 0x400;
  120.                 fprintf(wfp, "%s\n", RTrim(Line));
  121.              }
  122.              fclose(fp); fclose(wfp); if (!Index) unlink(BakFileName);
  123.           } else fclose(fp);
  124.           Fill  = Dirty = 0;
  125.           if (Index > 1 && *Text) {
  126.              sprintf(Line, "COPY %s %s", FileName, Text);
  127.              system(Line); strcpy(FileName, Text);
  128.           }
  129.           fp = fopen(FileName, "r");
  130.        }
  131.        break;
  132.     case 'L':                                           /* Load */
  133.        {
  134.           auto  char Line[256];
  135.  
  136.           if (fp != NULL) Rampage("Close", NULL, Index);
  137.           if (RamPage IS NULL)
  138.              while ((RamPage =  malloc(SizeOfRamPage)) IS NULL)
  139.                 if ((SizeOfRamPage >>= 2) < 256) exit(1);
  140.           if (!FileExists(Text)) return 0;
  141.           fp = fopen(Text, "r"); strcpy(FileName, Text);
  142.           if (!NuiPukaPau) NuiPukaPau += PtrAlloc();
  143.           Pau = Fill = Dirty = 0; StrPau = 21;
  144.           while (++Pau < 32767) {               /* 32K Lines Max */
  145.              if (Pau >= NuiPukaPau) NuiPukaPau += PtrAlloc();
  146.              NuiPuka(Pau) = ftell(fp) + 0x400;
  147.              if (fgets(Line, 255, fp) IS NULL) break;
  148.              StrPau = max(StrPau, min(strlen(Line)+11, 255));
  149.           }
  150.           Nuff = min(SizeOfRamPage/StrPau, 1023);
  151.           return Pau;
  152.        }
  153.     case 'C':                                           /* Close */
  154.        if (Index IS 1 && Dirty) Rampage("Save", NULL, 1);
  155.        for (i = 0; i < 32; i++) 
  156.           if (Puka[i] != NULL) { farfree(Puka[i]); Puka[i] = NULL; }
  157.        if (RamPage != NULL) farfree(RamPage); RamPage = NULL; 
  158.        NuiPukaPau = Pau = 0; fclose(fp);
  159.     }
  160.     return TRUE;
  161. }
  162.  
  163. static int PtrAlloc(void)
  164. {
  165.  /* Allocate another 4K RAM Block & Return Incr for NuiPukaPau */
  166.     int Index;
  167.  
  168.     for (Index = 0; Index < 31 && (Puka[Index] != NULL); Index++);
  169.     if (Index > 31) return 0;
  170.     Puka[Index] = calloc(1024, sizeof(long));
  171.     if (Puka[Index] IS NULL) { Rampage("Close", NULL, 1); exit(1); }
  172.     if (Index IS 31) return 1023; else return 1024;
  173. }
  174.  
  175.